#include <stdio.h>
#include <ctype.h>
#include <string.h>

#define MAX_str_LEN 100

char buffer[1000];     // 源程序缓冲区
int p = 0;             // 缓冲区指针
char ch;               // 当前字符
char str[MAX_str_LEN]; // 存放单词字符串
int syn;               // 单词种别码
int sum;               // 存放整型常数

char *keywords[] = {"begin", "if", "then", "while", "do", "end"};
int keyword_syn[] = {1, 2, 3, 4, 5, 6};

void scanner()
{
    int i = 0;
    while (buffer[p] == ' ' || buffer[p] == '\t' || buffer[p] == '\n')
        p++;
    ch = buffer[p++];

    // 注释处理
    if (ch == '/')
    {
        ch = buffer[p++];
        // 单行
        if (ch == '/')
        {
            while (buffer[p] != '\n' && buffer[p] != '#')
                p++;
            p++;
            scanner(); // 处理下一行
            return;
        }
        // 多行
        else if (ch == '*')
        {
            while (1)
            {
                ch = buffer[p++];
                if (ch == '*' && buffer[p] == '/')
                {
                    p++;
                    break;
                }
                if (ch == '#')
                {
                    printf("error:unclosed\n");
                    syn = -1;
                    return;
                }
            }
            scanner();
            return;
        }
        // 除法运算符
        else
        {
            p--;
            syn = 16;
            str[0] = '/';
            str[1] = '\0';
            return;
        }
    }

    // 关键字处理
    if (isalpha(ch))
    {
        while (isalnum(ch))
        {
            str[i++] = ch;
            ch = buffer[p++];
        }
        p--;
        str[i] = '\0';
        // 检查是否是关键字
        syn = 10;
        for (int j = 0; j < 6; j++)
        {
            if (strcmp(str, keywords[j]) == 0)
            {
                syn = keyword_syn[j];
                break;
            }
        }
    }
    // 数字处理
    else if (isdigit(ch))
    {
        sum = 0;
        while (isdigit(ch))
        {
            sum = sum * 10 + (ch - '0');
            ch = buffer[p++];
        }
        p--;
        syn = 11;
    }
    // 运算符处理
    else
    {
        switch (ch)
        {
        case ':':
            ch = buffer[p++];
            if (ch == '=')
            {
                syn = 18;
                str[0] = ':';
                str[1] = '=';
                str[2] = '\0';
            }
            else
            {
                syn = 17;
                str[0] = ':';
                str[1] = '\0';
                p--;
            }
            break;
        case '<':
            ch = buffer[p++];
            if (ch == '=')
            {
                syn = 22;
                str[0] = '<';
                str[1] = '=';
                str[2] = '\0';
            }
            else if (ch == '>')
            {
                syn = 21;
                str[0] = '<';
                str[1] = '>';
                str[2] = '\0';
            }
            else
            {
                syn = 20;
                str[0] = '<';
                str[1] = '\0';
                p--;
            }
            break;
        case '>':
            ch = buffer[p++];
            if (ch == '=')
            {
                syn = 24;
                str[0] = '>';
                str[1] = '=';
                str[2] = '\0';
            }
            else
            {
                syn = 23;
                str[0] = '>';
                str[1] = '\0';
                p--;
            }
            break;
        case '=':
            syn = 25;
            str[0] = '=';
            str[1] = '\0';
            break;
        case '+':
            syn = 13;
            str[0] = '+';
            str[1] = '\0';
            break;
        case '-':
            syn = 14;
            str[0] = '-';
            str[1] = '\0';
            break;
        case '*':
            syn = 15;
            str[0] = '*';
            str[1] = '\0';
            break;
        case '/':
            syn = 16;
            str[0] = '/';
            str[1] = '\0';
            break;
        case ';':
            syn = 26;
            str[0] = ';';
            str[1] = '\0';
            break;
        case '(':
            syn = 27;
            str[0] = '(';
            str[1] = '\0';
            break;
        case ')':
            syn = 28;
            str[0] = ')';
            str[1] = '\0';
            break;
        case '#':
            syn = 0;
            str[0] = '#';
            str[1] = '\0';
            break;
        default:
            syn = -1;
            str[0] = ch;
            str[1] = '\0';
            break;
        }
    }
}

// 表达式分析过程
int expression();
// 项分析过程
int term();
// 因子分析过程
int factor();

// 语句分析
void statement()
{
    int kk = 0;
    if (syn == 10){
        scanner(); // 读入单词符号
        if (syn == 18){
            scanner(); 
            if (!expression()){
                printf("error: 表达式错误\n");
                kk = 1;
            }
        }
        else{
            printf("error: 赋值号错误\n");
            kk = 1;
        }
    }
    else{
        printf("error: 语句号错误\n");
        kk = 1;
    }
}

// 语句串分析
void yucu()
{
    statement();
    while (syn == 26)
    {
        scanner(); // 读入下一个单词符号
        statement();
    }
}

// 因子分析
int factor()
{
    if (syn == 10 || syn == 11){
        scanner();
        return 1;
    }
    else if (syn == 27){
        scanner();
        if (expression()){
            if (syn == 28){
                scanner();
                return 1;
            }
        }
    }
    return 0;
}

// 项分析
int term()
{
    if (factor())
    {
        while (syn == 15 || syn == 16)
        {
            scanner();
            if (!factor()){
                return 0;
            }
        }
        return 1;
    }
    return 0;
}

// 表达式分析
int expression()
{
    if (term()){
        while (syn == 13 || syn == 14)
        {
            scanner();
            if (!term()){
                return 0;
            }
        }
        return 1;
    }
    return 0;
}
void test()
{
    p = 0;
    scanner();
    if (syn == 1){
        scanner();
        yucu();
        if (syn == 6){
            scanner();
            if (syn == 0){
                printf("success\n");
            }
            else{
                printf("error\n");
            }
        }
        else{
            printf("error\n");
        }
    }
    else{
        printf("error\n");
    }
}
int main()
{
    
    // do
    // {
    //     ch = getchar();
    //     buffer[p++] = ch;
    // } while (ch != '#'); // 输入
    FILE *fp;
    char filename[] = "mytest.txt"; 

    fp = fopen(filename, "r");
    if (fp == NULL) {
        printf("fopen error\n");
        return 1;
    }
    // 读数据
    while ((ch = fgetc(fp)) != EOF) {
        buffer[p++] = ch;
    }
    buffer[p] = '\0'; 
    fclose(fp);
    
    test();
    
    return 0;
}

// int main() {
//     printf("Please input string:");
//     do {
//         ch = getchar();
//         buffer
//     [p++] = ch;
//     } while (ch != '#');//输入源程序字符串，送入缓冲区

//     p = 0;
//     do {
//         scanner();//调用扫描子程序
//         switch(syn)
//         {
//             case 11:
//                 printf("(%d, %d)\n", syn, sum);
//                 break;
//             case -1:
//                 printf("error:%s\n", str);
//                 break;
//             default:
//                 printf("(%d, %s)\n", syn, str);
//         }
//     } while (syn != 0);

//     return 0;
// }